#include <stdlib.h>
#include <string>
#include <iostream>
#include <rise/common/exmacros.h>
#include <rise/common/Log.h>
#include <rise/common/Exception.h>
#include <rise/threading/Thread.h>
#include <staff/common/DataObject.h>
#include <staff-mq/client/Message.h>
#include <staff-mq/client/Subscriber.h>


class MyMessageHandler: public smq::MessageHandler
{
public:
  virtual void operator()(smq::Subscriber& rSubscriber, const smq::Message& rMsg)
  {
    const staff::CDataObject& tdoMsg = rMsg.tdoMessage;

    std::cout << "\n\n\033[1mMessageHandler1.\033[0m Message arrived: \n"
        << "msgid: " << rMsg.sId << std::endl
        << "queue: " << rMsg.sQueue << std::endl
        << "publisher: " << rMsg.sPublisher << std::endl
        << "Message: " << tdoMsg.GetText() << std::endl;
  }
};

int main(int nArgs, char* szArgs[])
{
  std::string sServerHost = "127.0.0.1";
  unsigned short ushServerPort = 8768;

  for (int nArg = 1; nArg < nArgs; ++nArg)
  {
    if(szArgs[nArg])
    {
      const std::string& sArg = std::string(szArgs[nArg]);
      if (sArg.substr(0, 2) == "-s")
      {
        sServerHost = sArg.substr(2);
      }
      else
      if (sArg.substr(0, 2) == "-p")
      {
        ushServerPort = static_cast<unsigned short>(atoi(sArg.substr(2).c_str()));
      }
      else
      if (sArg.substr(0, 2) == "-h")
      {
        std::cerr << "Subscriber multithreading sample: using start and stop functions.\n\n"
            << szArgs[0] << "[ -h][ -s<Server host>][ -p<port>]\n\n";
        return 0;
      }
      else
      {
        std::cerr << "unknown arg: " << sArg << "\n";
        return 1;
      }
    }
  }

  try
  {
    rise::LogEntry();

    MyMessageHandler tMessageHandler;

    smq::Subscriber tSubscriber;

    tSubscriber.Init("subscriber1", sServerHost, ushServerPort);

    std::cout << "subscribing to \"queue1\"" << std::endl;
    tSubscriber.SetHandler(&tMessageHandler);
    tSubscriber.Subscribe("queue1");

    tSubscriber.Start(true);

    rise::LogDebug() << "waiting 3 sec...";
    rise::threading::CThread::Sleep(3000);
    
    rise::LogDebug() << "stopping subscriber...";
    tSubscriber.Stop();
  }
  RISE_CATCH_ALL

  return 0;
}
